package com.yifeng.dao.impl;

import com.yifeng.common.Result;
import com.yifeng.common.SqlStatements;
import com.yifeng.dao.NewsDao;
import com.yifeng.model.News;
import com.yifeng.util.JdbcUtil;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;


public class NewsDaoImpl implements NewsDao {

    /*
    负责人：xiaoq

    功能：根据新闻类型列表查询新闻，支持按多种类型批量筛选

    参数：types - 新闻类型列表

    返回值：符合条件的新闻列表，异常时返回空列表
    */
    @Override
    public List<News> findByTypes(List<String> types) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<News> newsList=new ArrayList<>();

        try{
            conn= JdbcUtil.getConnection();
            //构建IN语句的占位符
            StringJoiner stringJoiner=new StringJoiner(",");
            for(int i=0;i<types.size();i++){
                stringJoiner.add("?");
            }
            //(%s)会被替换成(?,?)
            String sql=String.format(SqlStatements.NEWS_SELECT_BY_TYPES,stringJoiner.toString());
            //预处理
            pstmt=conn.prepareStatement(sql);
            //设置参数
            for(int i=0;i<types.size();i++){
                pstmt.setString(i+1,types.get(i));
            }

            //执行
            rs=pstmt.executeQuery();
            newsList=mapResultSetToList(rs);

        } catch (Exception e){
            e.printStackTrace();
        } finally {
            JdbcUtil.close(rs,pstmt,conn);
        }
        return newsList;
    }

    /*
    负责人：xiaoq

    功能：查询包含图片的新闻，用于展示有配图的新闻内容

    参数：无

    返回值：含图片的新闻列表，异常时返回空列表
    */
    @Override
    public List<News> findWithImages() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<News> newsList=new ArrayList<>();

        try{
            conn=JdbcUtil.getConnection();
            pstmt=conn.prepareStatement(SqlStatements.NEWS_SELECT_WITH_IMAGES);
            rs=pstmt.executeQuery();
            newsList=mapResultSetToList(rs);

        } catch (Exception e){
            e.printStackTrace();
        } finally {
            JdbcUtil.close(rs,pstmt,conn);
        }
        return newsList;
    }

    /*
    负责人：xiaoq

    功能：根据关键词在标题和内容中模糊搜索新闻，支持新闻搜索功能

    参数：keyword - 搜索关键词

    返回值：匹配关键词的新闻列表，异常时返回空列表
    */
    @Override
    public List<News> searchByKeyword(String keyword) {
        Connection conn=null;
        PreparedStatement pstmt=null;
        ResultSet rs=null;
        List<News> newsList=new ArrayList<>();

        try{
            // 添加调试信息
            System.out.println("=== DAO层调试 ===");
            System.out.println("DAO接收关键词: " + keyword);
            System.out.println("SQL语句: " + SqlStatements.NEWS_SEARCH_BY_KEYWORD);

            conn=JdbcUtil.getConnection();
            pstmt=conn.prepareStatement(SqlStatements.NEWS_SEARCH_BY_KEYWORD);
            String searchKeyword="%"+keyword+"%";
            //设置参数
            pstmt.setString(1,searchKeyword);
            pstmt.setString(2,searchKeyword);

            //执行
            rs=pstmt.executeQuery();
            newsList=mapResultSetToList(rs);

        } catch (Exception e){
            e.printStackTrace();
        } finally {
            JdbcUtil.close(rs,pstmt,conn);
        }
        return newsList;
    }

    /*
    负责人：xiaoq

    功能：分页查询新闻列表，支持前台新闻列表的分页展示

    参数：offset - 数据偏移量, pageSize - 每页记录数

    返回值：当前页的新闻列表，异常时返回空列表
    */
    @Override
    public List<News> findPaginated(int offset, int pageSize) {
        Connection conn=null;
        PreparedStatement pstmt=null;
        ResultSet rs=null;
        List<News> newsList=new ArrayList<>();

        try{
            conn=JdbcUtil.getConnection();
            pstmt=conn.prepareStatement(SqlStatements.NEWS_FIND_ALL_PAGINATED);
            pstmt.setInt(1,pageSize);
            pstmt.setInt(2,offset);
            rs=pstmt.executeQuery();
            newsList=mapResultSetToList(rs);

        } catch (Exception e){
            e.printStackTrace();
        } finally {
            JdbcUtil.close(rs,pstmt,conn);
        }
        return newsList;
    }

    /*
    负责人：xiaoq

    功能：根据新闻ID查询单条已发布新闻详情，用于前台新闻详情页展示

    参数：newsId - 新闻唯一标识ID

    返回值：新闻对象，未找到或未发布返回null
    */
    @Override
    public News findById(int newsId) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        News news=null;

        try{
            conn=JdbcUtil.getConnection();
            pstmt=conn.prepareStatement(SqlStatements.NEWS_FIND_BY_ID);
            pstmt.setInt(1,newsId);
            rs=pstmt.executeQuery();

            if(rs.next()){
                news=mapResultSetToNews(rs);
            }
        } catch (Exception e){
            e.printStackTrace();
        } finally {
            JdbcUtil.close(rs,pstmt,conn);
        }
        return news;
    }

    /*
    负责人：xiaoq

    功能：分页查询所有新闻，支持后台管理系统的新闻列表展示

    参数：offset - 数据偏移量, limit - 每页记录数

    返回值：新闻列表，异常时返回空列表
    */
    @Override
    public List<News> findAllPaginated(int offset, int limit) {
        Connection conn=null;
        PreparedStatement pstmt=null;
        ResultSet rs=null;
        List<News> newsList=new ArrayList<>();

        try{
            conn=JdbcUtil.getConnection();
            pstmt=conn.prepareStatement(SqlStatements.NEWS_FIND_ALL_PAGINATED);
            pstmt.setInt(1,limit);
            pstmt.setInt(2,offset);
            rs=pstmt.executeQuery();
            newsList=mapResultSetToList(rs);

        } catch (Exception e){
            e.printStackTrace();
        }finally {
            JdbcUtil.close(rs,pstmt,conn);
        }
        return newsList;
    }

    /*
    负责人：xiaoq

    功能：按状态分页查询新闻，支持按新闻状态筛选管理

    参数：status - 新闻状态, offset - 数据偏移量, limit - 每页记录数

    返回值：指定状态的新闻列表，异常时返回空列表
    */
    @Override
    public List<News> findByStatusPaginated(int status, int offset, int limit) {
        Connection conn=null;
        PreparedStatement pstmt=null;
        ResultSet rs=null;
        List<News> newsList=new ArrayList<>();

        try{
            conn=JdbcUtil.getConnection();
            pstmt=conn.prepareStatement(SqlStatements.NEWS_FIND_BY_STATUS_PAGINATED);
            pstmt.setInt(1,status);
            pstmt.setInt(2,limit);
            pstmt.setInt(3,offset);
            rs=pstmt.executeQuery();
            newsList=mapResultSetToList(rs);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(rs,pstmt,conn);
        }
        return newsList;
    }


    /*
    负责人：xiaoq

    功能：检查新闻ID是否存在，用于新闻操作前的验证

    参数：newsId - 新闻唯一标识ID

    返回值：存在返回true，不存在返回false
    */
    @Override
    public boolean existsById(Integer newsId) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        boolean exists=false;

        try{
            conn=JdbcUtil.getConnection();
            pstmt=conn.prepareStatement(SqlStatements.NEWS_EXISTS_BY_ID);
            pstmt.setInt(1,newsId);
            rs=pstmt.executeQuery();

            if(rs.next()){
                //获取该列数据判断是否大于0
                exists=rs.getInt(1)>0;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(rs,pstmt,conn);
        }
        return exists;

    }

    /*
    负责人：xiaoq

    功能：插入新新闻记录，用于新闻发布功能，支持获取自增主键

    参数：news - 包含新闻信息的News对象

    返回值：插入成功返回true，失败返回false
    */
    @Override
    public boolean insert(News news) {
        Connection conn=null;
        PreparedStatement pstmt=null;
        boolean flag=false;

        try{
            conn=JdbcUtil.getConnection();
            //Statement.RETURN_GENERATED_KEYS用于获取新增记录的自增主键
            pstmt=conn.prepareStatement(SqlStatements.NEWS_INSERT,Statement.RETURN_GENERATED_KEYS);
            pstmt.setString(1,news.getTitle());
            pstmt.setString(2,news.getContent());
            pstmt.setString(3,news.getCategory());
            pstmt.setString(4,news.getAuthor());
            pstmt.setString(5,news.getPicNew());
            pstmt.setByte(6,news.getStatus());

            flag=pstmt.executeUpdate()>0;

            //获取自增主键
            if(flag){
                ResultSet rs=pstmt.getGeneratedKeys();
                if(rs.next()){
                    //getInt(1) 表示获取结果集第一列的整数值（即自动生成的 newsId）
                    //将获取到的主键值设置到 news 对象的 newsId 字段中
                    news.setNewsId(rs.getInt(1));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(pstmt,conn);
        }
        return flag;
    }

    /*
    负责人：xiaoq

    功能：更新新闻记录，用于新闻编辑功能

    参数：news - 包含更新后新闻信息的News对象

    返回值：更新成功返回true，失败返回false
    */
    @Override
    public boolean update(News news) {
        Connection conn=null;
        PreparedStatement pstmt=null;
        boolean flag=false;



        try{
            if(news.getPicNew()!=null){
                conn=JdbcUtil.getConnection();
                pstmt=conn.prepareStatement(SqlStatements.NEWS_UPDATE);
                pstmt.setString(1,news.getTitle());
                pstmt.setString(2,news.getContent());
                pstmt.setString(3,news.getCategory());
                pstmt.setString(4,news.getAuthor());
                pstmt.setString(5,news.getPicNew());
                pstmt.setByte(6,news.getStatus());
                pstmt.setInt(7,news.getNewsId());
            }else{
                conn=JdbcUtil.getConnection();
                pstmt=conn.prepareStatement("UPDATE tb_news SET title = ?, content = ?, category = ?, author = ?, status = ?, update_time = CURRENT_TIMESTAMP WHERE news_id = ?");
                pstmt.setString(1,news.getTitle());
                pstmt.setString(2,news.getContent());
                pstmt.setString(3,news.getCategory());
                pstmt.setString(4,news.getAuthor());
                pstmt.setByte(5,news.getStatus());
                pstmt.setInt(6,news.getNewsId());
            }


            flag=pstmt.executeUpdate()>0;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(pstmt,conn);
        }
        return flag;
    }

    /*
    负责人：xiaoq

    功能：根据新闻ID删除新闻记录，实现新闻管理中的删除功能

    参数：newsId - 新闻唯一标识ID

    返回值：删除成功返回true，失败返回false
    */
    @Override
    public boolean deleteById(Integer newsId) {
        Connection conn=null;
        PreparedStatement pstmt=null;
        boolean flag=false;
        
        try{ 
            conn=JdbcUtil.getConnection();
            pstmt=conn.prepareStatement(SqlStatements.NEWS_DELETE_BY_ID);
            pstmt.setInt(1,newsId);
            flag=pstmt.executeUpdate()>0;
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(pstmt,conn);
        }
        return flag;
    }

    /*
    负责人：xiaoq

    功能：将ResultSet单条记录映射为News对象，用于单个新闻查询

    参数：rs - 数据库查询结果集

    返回值：News对象
    */
    private News mapResultSetToNews(ResultSet rs) throws SQLException {
        News news = new News();
        //映射字段
        news.setNewsId(rs.getInt("news_id"));
        news.setTitle(rs.getString("title"));
        news.setContent(rs.getString("content"));
        news.setCategory(rs.getString("category"));
        news.setAuthor(rs.getString("author"));

        //处理时间字段(发布时间/更新时间)
        Timestamp publishTime = rs.getTimestamp("publish_time");
        if(publishTime != null){
            news.setPublishTime(publishTime.toLocalDateTime());
        }
        Timestamp updateTime = rs.getTimestamp("update_time");
        if(updateTime != null){
            news.setUpdateTime(updateTime.toLocalDateTime());
        }

        //映射剩余字段
        news.setViewCount(rs.getInt("view_count"));
        news.setStatus(rs.getByte("status"));
        news.setPicNew(rs.getString("pic_new"));

        return news;
    }

    /*
    负责人：xiaoq

    功能：将ResultSet结果集转换为News对象列表，用于多个查询方法的公共处理逻辑

    参数：rs - 数据库查询结果集

    返回值：News对象列表
    */
    private List<News> mapResultSetToList(ResultSet rs) throws SQLException {
        List<News> list = new ArrayList<>();
        while (rs.next()) {
            list.add(mapResultSetToNews(rs));
        }
        return list;
    }



    //不分页返回新闻
    @Override
    public List<News> findByStatus(int status) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<News> newsList = new ArrayList<>();

        try {
            conn = JdbcUtil.getConnection();
            pstmt = conn.prepareStatement(SqlStatements.NEWS_FIND_BY_STATUS);
            pstmt.setInt(1, status);
            rs = pstmt.executeQuery();
            newsList = mapResultSetToList(rs);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(rs, pstmt, conn);
        }
        return newsList;
    }

    @Override
    public List<News> findAll() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<News> newsList = new ArrayList<>();

        try {
            conn = JdbcUtil.getConnection();
            pstmt = conn.prepareStatement(SqlStatements.NEWS_FIND_ALL);
            rs = pstmt.executeQuery();
            newsList = mapResultSetToList(rs);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(rs, pstmt, conn);
        }
        return newsList;
    }

}